#ifndef _ut_h
#define _ut_h

#include <stdio.h>
#include <stdlib.h>

const UnrealPkgSig = 0x9E2A83C1;
const BUFF_SIZE = 1024;

const char *ID_NAME_U1  = "Unreal";
const char *ID_NAME_RTN = "Unreal - Return To Na Pali";
const char *ID_NAME_U2  = "Unreal II";
const char *ID_NAME_UT  = "Unreal Tournament";
const char *ID_NAME_UT2 = "Unreal Tournament 2003";

typedef enum {mtNotUnrealPkg = 0x0,
                   mtUnknown = 0x1,
                    mtUnreal = 0x2,
                    mtNaPali = 0x3,
                   mtUnreal2 = 0x4,
                        mtUT = 0x5,
                    mtUT2003 = 0x6
              } UFileType ;

typedef unsigned int dword;

typedef struct {
	unsigned long  Data1;
	unsigned short Data2;
	unsigned short Data3;
	unsigned char  Data4[8];
} UGUID;

typedef struct
{
   dword	Signature;	       		//0x9E2A83C1
   dword	PackageVersion;	   		//Low order WORD is the file version, high order WORD is the LicenseeMode in newer versions (seems unused).
   dword	PackageFlags;			//See "Package Flags"
   dword	NameCount;				//Number of names in the Name Table
   dword	NameOffset;				//Offset of the Name Table from the beginning of the file
   dword	ExportCount;			//Number of objects in the Export Table
   dword	ExportOffset;			//Offset of the Export Table from the beginning of the file
   dword	ImportCount;			//Number of objects in the Import Table
   dword	ImportOffset;			//Offset of the Import Table from the beginning of the file 
//    If PackageVersion<68 then
   dword	HeritageCount;			//Number of values in the Heritage Table
   dword	HeritageOffset;			//Offset of the Heritage Table from the beginning of the file
//   Else
   UGUID	PkgGUID;				
   dword	GenerationCount;		//Unknown meaning of "Generation". Seems to be related to recompilation.
//   For each generation
//   dword	ExportCount;	
//   dword	NameCount;	
//   EndIf
} pMainHeader;

typedef int INDEX;

typedef struct
{
	INDEX	Class;
	INDEX	Super;
	dword	Package;
	INDEX	ObjectName;
	dword	ObjectFlags;
	INDEX	SerialSize;
	INDEX	SerialOffset;
} pExportItem;

typedef struct
{
	INDEX	ClassPackage;
	INDEX	ClassName;
	dword	Package;
	INDEX	ObjectName;
} pImportItem;


typedef char NAME[MAX_PATH]; 

typedef struct
{
	NAME	ObjectName;
	dword	ObjectFlags;
} pNameItem;

typedef pNameItem NameTable[];
typedef pExportItem ExportTable[];
typedef pImportItem ImportTable[];

   // findflags
const int  FIND_NAME  = 0x02;
const int  FIND_CLASS = 0x04;
const int  SEARCH_EXPORTS = 0x08;
const int  SEARCH_IMPORTS = 0x10;
const int  SEARCH_NAMES   = 0x20;

int LoadPkgFile(char *fn, pMainHeader *hdr, NameTable **name, ExportTable **export, ImportTable **import, FILE **PKG_FILE);
int RawExtractObject(FILE *fh, ExportTable *export, int idx, char *tofile);
int UnloadFile(FILE *fh, NameTable *NameT, ExportTable *ExportT, ImportTable *ImportT);


/* helper functions */
int get_idx(int raw_idx);
int read_name(FILE *file, pMainHeader *header, pNameItem *name);
int read_asciiz(FILE *file, char *buffer, int size, int length);
int read_idx(FILE *hFile);
int read_int(FILE *hFile);
char read_byte(FILE *hFile);
int write_buffer(FILE *file, void *buffer, int size);
int read_buffer(FILE *file, void *buffer, int size);
int fsize(FILE *file);
char *get_name(NameTable *names, ExportTable *exports, ImportTable *imports, int idx, int type, int class_or_name);
UFileType getUFileTypeByVer(int ver);
UFileType getUFileTypeByName(char *fn);
const char *getNameByType(UFileType ft);

#include "ut.c"

#endif //_ut_h

